#include "stdafx.h"
#include "ConfigWriterXML.h"
#include "tinyxml.h"
#include "Log\Log.h"

namespace woe
{
	ConfigWriterXML*	ConfigWriterXML::m_Instance = NULL;

	ConfigWriterXML::ConfigWriterXML()
	{
		//InitializeCriticalSection( &m_csWriteXml );
	}

	ConfigWriterXML::~ConfigWriterXML()
	{
		//DeleteCriticalSection( &m_csWriteXml );
		if ( m_Instance )
		{
			delete m_Instance;
			m_Instance = NULL;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	TiXmlElement* ConfigWriterXML::FindOrCreateElement(TiXmlDocument& doc, const std::string& elemName, TiXmlElement* parentElement)
	{
		TiXmlElement* element;

		// add to the document if we have no parent element
		if (parentElement == NULL)
		{
			element = doc.FirstChildElement(elemName.c_str());
		}
		else
		{
			element = parentElement->FirstChildElement(elemName.c_str());
		}

		if (element == NULL)
		{
			element = new TiXmlElement(elemName.c_str());
			if (parentElement == NULL)
			{
				doc.LinkEndChild(element);
			}
			else
			{
				parentElement->LinkEndChild(element);
			}
		}

		return element;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	bool ConfigWriterXML::DoSave(const std::string& strFileName, IConfigOperator* config)
	{
		TiXmlDocument doc;

		if ( !config )
		{
			LOG_DEBUG("Failed to , ConfigWriterXML::DoSave, the param config is NULL\n");
			return false;
		}

		//::EnterCriticalSection( &m_csWriteXml );

		TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );

		std::string key , value;
		while( config->GetNext(key,value) )
		{
			// a config file is setup to be each element seperated by a '.'
			// this '.' represents a chile element
			// attributes are not supported during writing we would
			// need to change our Load to differentiate between attributes
			// and elements.
			// a '.' is used to seperate attributes from the key

			// create our element tree
			size_t elementIndex = key.find_first_of('.');
			vector<std::string> elements;
			while (elementIndex < key.length())
			{
				std::string elemName = key.substr(0, elementIndex);
				elements.push_back(elemName);
				key = key.substr(elementIndex+1);
				elementIndex = key.find_first_of('.');
			}
			elements.push_back(key);

			// loop through all our elements and get our parent element
			TiXmlElement* element = NULL;

			for (size_t i = 0; i < elements.size(); i++)
			{
				element = FindOrCreateElement(doc, elements[i], element);
			}

			// add the value to our current element
			TiXmlText* text = new TiXmlText(value.c_str());
			if(NULL != element)
			{
				element->LinkEndChild(text);
			}
		}

		doc.SaveFile(strFileName);

		//::LeaveCriticalSection( &m_csWriteXml );
		return true;
	}

	ConfigWriterXML* ConfigWriterXML::GetInstance()
	{
		if ( !m_Instance )
		{
			m_Instance = new ConfigWriterXML;
		}
		return m_Instance;
	}
}